package com.syh.jn.scm.service.impl.supplier.stock;

import cn.redscarf.commons.wrapper.Wrapper;
import com.alibaba.dubbo.config.annotation.Service;
import com.syh.core.ddd.domain.DomainEvent;
import com.syh.core.ddd.event.DomainEventBus;
import com.syh.core.ddd.event.annotation.DomainEventHandle;
import com.syh.jn.scm.domain.operation.entity.supplier.OperaSupplier;
import com.syh.jn.scm.domain.operation.event.supplier.OperaSupplierEvent;
import com.syh.jn.scm.domain.supplier.entity.stock.StockOtherInBill;
import com.syh.jn.scm.domain.supplier.event.StockOtherInBillEvent;
import com.syh.jn.scm.domain.supplier.repository.stock.StockOtherInBillReadRepository;
import com.syh.jn.scm.domain.supplier.repository.stock.StockOtherInBillRepository;
import com.syh.jn.scm.dto.supplier.stock.StockOtherInBillItemVo;
import com.syh.jn.scm.dto.supplier.stock.StockOtherInBillMto;
import com.syh.jn.scm.dto.supplier.stock.StockOtherInBillSto;
import com.syh.jn.scm.dto.supplier.stock.StockOtherInBillVo;
import com.syh.jn.scm.infrastructure.eventBus.reflex.ReflexEventBus;
import com.syh.jn.scm.service.api.supplier.stock.StockOtherInBillService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;

/**
 * 其他入库单管理
 */
@Service
@Transactional
public class StockOtherInBillServiceImpl implements StockOtherInBillService {

  @Autowired
  private StockOtherInBillRepository stockOtherInBillRepositoryImpl;
  @Resource(name = "stockOtherInBillReadRepositoryMbImpl")
  private StockOtherInBillReadRepository stockOtherRecordBillInRepositoryMbImpl;


  @Override
  public Long save(StockOtherInBillSto stockOtherInBillSto) {
    StockOtherInBill stockOtherInBill = new StockOtherInBill(stockOtherInBillSto);
    return stockOtherInBillRepositoryImpl.add(stockOtherInBill);
  }


  @Override
  public void update(StockOtherInBillMto stockOtherInBillMto) {
    StockOtherInBill stockOtherInBill = this.stockOtherInBillRepositoryImpl.getById(stockOtherInBillMto.getId(), false);
    stockOtherInBill.modify(stockOtherInBillMto);
    this.stockOtherInBillRepositoryImpl.update(stockOtherInBill);
  }

  @Override
  public void delete(Long id) {
    StockOtherInBill stockOtherInBill = stockOtherInBillRepositoryImpl.getById(id, false);
    stockOtherInBill.destroy();
    stockOtherInBillRepositoryImpl.removeById(id);
  }

  @Override
  public StockOtherInBillVo getById(Long id) {
    StockOtherInBillVo stockOtherInBillVo = this.stockOtherRecordBillInRepositoryMbImpl.getById(id);
    List<StockOtherInBillItemVo> stockOtherInBillItemVos = this.stockOtherRecordBillInRepositoryMbImpl.findStockOtherInBillItemVoByBillId(id);
    stockOtherInBillVo.setItems(stockOtherInBillItemVos);
    return stockOtherInBillVo;
  }

  @Override
  public void cancel(Long id) {
    StockOtherInBill stockOtherInBill = this.stockOtherInBillRepositoryImpl.getById(id, false);
    stockOtherInBill.cancel();
    this.stockOtherInBillRepositoryImpl.update(stockOtherInBill, false);
  }

  @Override
  public void confirm(Long id, Long recordDateTimestamp) {
    StockOtherInBill stockOtherInBill = this.stockOtherInBillRepositoryImpl.getById(id);
    stockOtherInBill.confirm(recordDateTimestamp);
    this.stockOtherInBillRepositoryImpl.update(stockOtherInBill, false);
    this.publicEvent(StockOtherInBillEvent.buildStockOtherInBillConfirmStatus(new Object[]{stockOtherInBill}));
  }

  @Override
  public void cancelConfirm(Long id) {
    StockOtherInBill stockOtherInBill = this.stockOtherInBillRepositoryImpl.getById(id);
    StockOtherInBill oldBill = this.stockOtherInBillRepositoryImpl.getById(id);
    stockOtherInBill.cancelConfirm();
    this.stockOtherInBillRepositoryImpl.update(stockOtherInBill, false);
    this.publicEvent(StockOtherInBillEvent.buildStockOtherInBillCancelConfirmStatus(new Object[]{stockOtherInBill,oldBill}));
  }

  @Override
  public void unLock(Long id) {
    StockOtherInBill stockOtherInBill = this.stockOtherInBillRepositoryImpl.getById(id);
    stockOtherInBill.unLock();
    this.stockOtherInBillRepositoryImpl.update(stockOtherInBill, false);
  }

  @Override
  public boolean contains(Long id) {
    return stockOtherInBillRepositoryImpl.contains(id);
  }

  @Override
  public List<StockOtherInBillVo> findList(Wrapper wrapper) {
    return this.stockOtherRecordBillInRepositoryMbImpl.getList(wrapper);
  }

  @Override
  public List<StockOtherInBillVo> findListPage(Wrapper wrapper, Integer startRow, Integer count) {
    return this.stockOtherRecordBillInRepositoryMbImpl.findListPage(wrapper, startRow, count);
  }

  @Override
  public StockOtherInBillVo getOne(Wrapper wrapper) {
    return this.stockOtherRecordBillInRepositoryMbImpl.getOne(wrapper);
  }

  @Override
  public int getCount(Wrapper wrapper) {
    return this.stockOtherRecordBillInRepositoryMbImpl.getCount(wrapper);
  }

  @Override
  public List<StockOtherInBillItemVo> findStockOtherInBillItemVoListByInBillId(Long stockOtherRecordBillId) {
    return stockOtherRecordBillInRepositoryMbImpl.findStockOtherInBillItemVoByBillId(stockOtherRecordBillId);
  }

  @Override
  public int getStockOtherInBillItemVoCount(Wrapper wrapper) {
    return stockOtherRecordBillInRepositoryMbImpl.findStockOtherInBillItemVoCount(wrapper);
  }

  @Override
  public List<StockOtherInBillItemVo> findStockOtherInBillItemVoListPage(Wrapper wrapper, Integer startRow, Integer count) {
    return this.stockOtherRecordBillInRepositoryMbImpl.findStockOtherInBillItemVoListPage(wrapper, startRow, count);
  }

  /**
   * 消费者：监听服务商反开账（删除所有该服务商的其他入库单）
   */
  @DomainEventHandle(OperaSupplierEvent.SUPPLIER_REVERSAL_ACCOUNT)
  protected void handleSupplierReversalAccount(OperaSupplier supplier) {
    this.stockOtherInBillRepositoryImpl.deleteByBusinessEntityId(supplier.getId());
  }

  /**
   * 发布事件
   *
   * @param event
   */
  //TODO 暂时先写在service内
  public void publicEvent(DomainEvent event) {
    DomainEventBus bus = ReflexEventBus.getEventBus();
    bus.publicEvent(event);
  }

}
